package com.young.springdemo.service.annotation;

import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @program: springdemo
 * @description 创建切入点
 * @author: Young
 * @create: 2020-05-27 14:50
 **/
@Component
@Slf4j
@Aspect
public class AspectParamCheck {

    //创建切入点
    @Around("@annotation(com.young.springdemo.service.annotation.HandleParam)")
    public Object paramCheck(ProceedingJoinPoint point) throws Throwable{
        //获取方法
        MethodSignature signature = (MethodSignature)point.getSignature();
        //获取参数名称
        String[] parameterNames = signature.getParameterNames();
        //获取参数值
        Object[] args = point.getArgs();
        //获取参数类型
        Class[] parameterTypes = signature.getParameterTypes();
        //获取方法上的HandleParam注解
        HandleParam handleParam = signature.getMethod().getAnnotation(HandleParam.class);
        String[] excludeParams  = handleParam.excludeParams();
        //数组转list
        List<String> excludeParamList  =Lists.newArrayList(excludeParams);
        String location = point.getTarget().toString() + "." + signature.getMethod().getName();
        for (int i = 0; i < args.length;i++ ){
            if (handleParam.notBlank()){
                //具体为空业务处理
                notBlank(location,excludeParamList,parameterNames[i],args[i],parameterTypes[i].getName());
            }else if (handleParam.notNull()){
                //具体为null业务处理
                notNull(location,excludeParamList,parameterNames[i],args[i],parameterTypes[i].getName());
            }
        }
        return point.proceed();

    }

    private void notNull(String location, List<String> excludeParamList, String parameterName, Object value, String paramType) {
        //如果该参数不在排除范围内,则校验
        if (!excludeParamList.contains(parameterName)){
            if (value ==null ){
                throw  new ParamBlankException(location+"Error:["+parameterName+"is Null,type is "+ paramType);
            }
        }
    }

    private void notBlank(String location, List<String> excludeParamList, String parameterName, Object value, String paramType) {
        if (!excludeParamList.contains(parameterName)){
            if (value==null || StringUtils.isBlank(value.toString())){
                throw  new ParamBlankException(location+"Error:["+parameterName+" is Blank,type is "+ paramType);
            }
        }
    }
}
